import type Field from '@src/model/Field';

import { t } from '@src/locales';
import { getCustomerListAsyn as getCustomerListAsync, getUserTag } from '@src/api/CustomerApi';
import { getTaskCustonerProductList as getTaskCustomerProductList, getTaskCustomerLinkman, getProductType } from '@src/api/TaskApi';
import { searchAllcatalog, productQualityManageList } from '@src/api/ProductV2Api';
import { getProviderData } from '@src/api/FieldApi.ts';
import { getProjectTableList } from '@src/api/ProjectManage.ts';
import { searchProductTypeList, getProvideAllLabel } from '@src/api/serviceProviderApi';
import { multiField, objectField } from './config'
import { getRoleList } from '@src/api/Repository';


// utils
import { genPlaceholder } from '@src/component/form/util';
import { OperatorType, isMultiValue } from './operator';
import { getComponentNamePrefix } from '@src/util/component';
import { parse } from '@src/util/lang/object'
import { isString } from '@src/util/type'
/* enum */
import TableNameEnum from '@model/enum/TableNameEnum';
import { ProjectManageFieldNameMappingEnum } from '@model/enum/FieldMappingEnum';
import { WarrantyServiceItemLabelEnum } from '@model/enum/LabelEnum'

// 远程搜索方法类型
export type RemoteMethodType = (...args: any[]) => Promise<any>;
export type MethodType = (...args: any[]) => any;
// 组件绑定值类型
export type CompBindType = {
  placeholder?: string;
  remoteMethod?: RemoteMethodType;
  multiple?: boolean;
  collapsed?: boolean;
  on?: Record<string, FunctionConstructor>;
  [key: string]: any;
};

// 常用 item
export type commonUseItemType = {
  fieldName: string;
  isChecked: boolean;
};

export type SearchItemType = {
  id: number; // id 唯一值
  field?: Field | null; // 字段
  fieldName: string; // 字段名
  value: any; // 值
  comp: string; // 组件名称
  bind: CompBindType; // 组件绑定数据
  operator: string; // 选中条件
  operators: OperatorType[]; // 条件配置
  isCommonUse: boolean; // 常用
};

/**
 * 搜索客户
 */
export function searchCustomer(params: any = {}) {
  return getCustomerListAsync(params)
    .then(res => {
      if (!res || !res.list) return Promise.reject('请求失败');

      res.list = res.list.map((customer: any) => {
        const { id, name, lmPhone, serialNumber } = customer;
        return { id, name, lmPhone, serialNumber };
      });
      return res;
    })
    .catch(e => console.error(e));
}

/**
 * 搜索客户
 */
export function searchProduct(params: any = {}) {
  // params.customerId = this.form.customer || '';
  return getTaskCustomerProductList(params)
    .then(res => {
      if (!res.result || !res.result?.list) return Promise.reject('请求失败');
      res.result.list = res.result.list.map((product: any) => {
        const { id, name, serialNumber, type, customerName, customerId } = product;
        return { id, name, serialNumber, type, customerName, customerId };
      });
      return res.result;
    })
    .catch(e => console.error(e));
}

/**
 * 搜索联系人
 */
export function searchLinkman(params: any = {}) {
  return getTaskCustomerLinkman(params)
    .then((res: any) => {
      if (!res || !res.success || !res.result?.list) {
        return Promise.reject('请求失败');
      }
      res.result.list = (res.result.list || []).map(({ displayName, userId, name, id, phone = '' }: any) => {
        return Object.freeze({
          name: displayName || name || '',
          id: userId || id || '',
          phone,
        });
      });
      return res.result;
    })
    .catch(e => console.error(e));
}

/**
 * 搜索用户
 */
export function searchUserTag(params: any = {}) {
  return getUserTag(params)
    .then((res: any) => {
      if (!res || !res.list) return Promise.reject('请求失败');
      res.list = res.list.map(({ displayName, userId, staffId, isDelete }: any) => {
        return Object.freeze({
          name: displayName + (isDelete == 1 ? ` (${t('common.base.resigned')})` : ''),
          id: userId,
          staffId,
          isDelete
        });
      });
      return res;
    })
    .catch(e => console.error(e));
}

/**
 * 查询产品类型
 * @param {String} params.keyword
 * @param {Number} params.pageNum
 */
export function searchRelatedCatalog(params: any = {}) {
  params.keyWord = params.keyword;
  return searchAllcatalog(params)
    .then((res: any) => {
      if (!res || !res.result?.list) return Promise.reject('请求失败');
      res.result.list = (res.result.list || []).map((item: any) => ({
        label: item.catalogName,
        value: item.id,
        key: item.id,
      }));
      return res.result;
    })
    .catch((err: unknown) => console.error('searchTaskManager function catch err', err));
}

/**
 * 故障库 查询产品类型
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchProductType(params: any = {}) {
  return getProductType(params)
    .then((res: any) => {
      if (!res || !res.result) return Promise.reject('请求失败');
      deleteProductTypeEmpty(res.result);
      res.result = (res.result || []).map((item: any) => ({
        ...item,
        key: item.id,
      }));

      return res.result;
    })
    .catch((err: unknown) => console.error('searchTaskManager function catch err', err));
}

/**
 * @description 删除产品类型空子集
 */
function deleteProductTypeEmpty(data: any = []) {
  try {
    data.forEach((item: any) => {
      if (!item.tasks.length) {
        delete item.tasks;
      } else {
        deleteProductTypeEmpty(item.tasks);
      }
    });
  } catch (error) {
    console.error(error);
  }
}

/**
 * 查询服务商
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchServiceProviders(params: any = {}) {
  params.depth = 1;
  params.pageSize = 10;
  return getProviderData(params)
  .then((res: any) => {
    if (!res || !res.result?.list) return Promise.reject('请求失败');
    res.result.list = (res.result.list || []).map((item: any) => ({
      label: item.name,
      value: item.tenantProviderId,
      key: item.tenantProviderId
    }));
    return res.result;
  })
  .catch((err: unknown) =>
    console.error('searchTaskManager function catch err', err)
  );
}
/**
 * 知识库查询角色
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchRole(params: any = {}) {
  return getRoleList(params)
  .then((res: any) => {
    if (!res || !res?.data) return Promise.reject('请求失败');
    res.data = (res.data || []).map((item: any) => ({
      label: item.text,
      value: item.id,
      key: item.id
    }));
    return res;
  })
  .catch((err: unknown) =>
    console.error('searchRole function catch err', err)
  );
}

/**
 * 查询服务项目名称
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchServiceItemName(params: any = {}) {
  params.pageSize = 10;
  return productQualityManageList(params)
    .then((res: any) => {
      if (!res || !res.result?.list) return Promise.reject(res.message);

      res.result.list = (res.result.list || []).map((item: any) => ({
        label: WarrantyServiceItemLabelEnum[item.svcProjectName] || item.svcProjectName,
        value: item.id,
        key: item.id,
      }));

      return res.result;
    })
    .catch((err: unknown) => console.error('searchServiceItemName function catch err', err));
}

/**
 * 任务管理-所属项目
 * @param {String} params.likeSearch
 */
 export function searchProjectId(params: any = {}) {
  const { pageSize, pageNum, keyword } = params;

  return getProjectTableList({
    pageSize,
    pageNum,
    likeSearch: keyword
  })
  .then((res: any) => {
    if (!res.success) return Promise.reject(res.message);

    res.result.list = (res?.result?.list || []).map((item: any) => ({
      label: item.projectName,
      value: item.id,
      key: item.id
    }));

    return res.result || [];
  })
  .catch((err: unknown) =>
    console.error('searchTaskType function catch err', err)
  );
}

/**
 * 查询授权产品目录
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchGetProductTypeList(params: any = {}) {
  let { keyword, pageNum, pageSize } = params;
  const dataToSend = {
    keyword,
    pageNum,
    pageSize
  };
  return searchProductTypeList(dataToSend)
  .then((res: any) => {
    
    if (!res || !res.result?.list) return Promise.reject('请求失败');
    res.result.list = (res.result.list || []).map((item: any) => ({
      label: item.name,
      value: item.id,
      id: item.id,
      key: item.id
    }));
    return res.result;
  })
  .catch((err: unknown) =>
    console.error('searchTaskManager function catch err', err)
  );
}

/**
 * 查询服务商标签
 * @param {String} params.keyword
 * @param {Number} params.depth
 */
export function searchProvideAllLabel(params: any = {}) {
  return getProvideAllLabel()
  .then((res: any) => {
    if (!res || !res.data) return Promise.reject('请求失败');
    res.data = (res.data || []).map((item: any) => ({
      label: item?.labelName || '',
      value: item?.id || '',
      id:  item?.id || '',
      key: item.id,
    }));
    return res;
  })
  .catch((err: unknown) =>
    console.error('searchTaskManager function catch err', err)
  );
}

/**
 * 搜索项 初始值
 * @param {SearchItemType} searchItem
 * @returns [] || {} || ''
 */
export function initValue(searchItem: SearchItemType) {
  const { field, operator } = searchItem;
  const { fieldName, formType, isSystem, setting } = field!;

  // object 处理
  if (objectField.includes(fieldName) || objectField.includes(formType)) return null;

  const isCommonUser = formType === 'user' && !isSystem; // 自定义user
  if (isCommonUser) return null;

  // 多选
  if (isMultiValue(operator) || multiField.includes(fieldName) || multiField.includes(formType)) return [];

  // select 处理
  if (formType === 'select') return setting.isMulti || !isSystem ? [] : '';

  // 多级选择
  if (formType === 'cascader') return [];

  // 多级选择
  if (formType === 'currency') return {
    number: null,
    currency: []
  };

  if (searchItem.comp === 'date-search') {
    // 日期类型处理
    if(['gt', 'lt', 'le', 'ge'].includes(searchItem.operator)){
      return ''
    }
    return searchItem.bind.type === 'date' ? '' : [];
  }

  return '';
}

// 特殊处理需要渲染的组件
const specialFieldCompMap: Record<string, string> = {
  // 自定义
  customer: 'customer-search', // 客户
  related_customer: 'customer-search', // 关联客户
  related_customers: 'customer-search', // 关联客户 --- 客户管理内为什么不一样？？？
  product: 'product-search', // 产品
  catalogId: 'remote-select-search', // 产品类型
  tags: 'tags-search', // 部门
  tlmName: 'linkman-search', // 联系人 - 工单
  related_task: 'task-search', // 关联工单
  serviceProviders: 'remote-select-search', // 服务商
  productType: 'product-type-search', // 故障库 产品类型
  parentCustomer: 'customer-search', // 上级客户

  // 下拉选择
  level: 'select-search', // 优先级
  serviceType: 'select-search', // 服务类型
  serviceContent: 'select-search', // 服务内容

  area: 'address-search', // 区域

  // 时间
  planStartTime: 'date-search', // 计划开始时间
  planEndTime: 'date-search', // 计划结束时间
  planTime: 'date-search', // 计划时间
  datetime: 'date-search', // 日期时间

  // 文本
  cusAddress: 'text-search', // 详细地址
  description: 'text-search', // 描述
  textarea: 'text-search', // 多行文本 ---> 单行文本
  phone: 'text-search', // 手机号
  email: 'text-search', // 邮箱
  location: 'text-search', // 位置
  relationCustomer: 'text-search', // 关联客户
  relationProduct: 'text-search', // 关联产品
  code: 'text-search', // 扫码

  // 数字
  formula: 'number-search', // 计算公式 ---> number

  serviceProviderQualification: 'select-search', // 服务商资质
  engineerQualification: 'select-search', // 工程师资质
  relationForm: 'text-search', // 关联工单

  serialNumber: 'text-search', // 连接器项目中的 编号
  connector_related_task: 'connector-related-task-search', // 连接器项目中的关联工单
  role: 'remote-select-search', // 连接器项目中的知识库角色
  rich_text: 'rich-text-search', // 连接器项目中的知识库角色
  svcProjectName: 'remote-select-search', // 服务项目名称
  projectId: 'remote-select-search', // 任务管理-所属项目
  productCustomerMultiAddress: 'address-multi-search', // 产品模块客户地址多选搜索
  authorizeProduct: 'remote-select-search', // 服务商-授权产品目录
  tagLabel: 'remote-select-search', // 服务商-标签

  // todo：json类型不支持固定值，但是“添加字段”默认“固定值” 会报错
  jsonArray: 'text-search',
  jsonObject: 'text-search',
};

export const createSearchItem = function (origin: Partial<SearchItemType> = {}): SearchItemType {
  return {
    id: ~~(Math.random() * 1000000),
    fieldName: '',
    field: null,
    value: null,
    comp: '',
    bind: {},
    operator: '',
    operators: [],
    isCommonUse: false,
    ...origin,
  };
};

type ComponentOption = {
  field: Field;
  operator: string;
  remoteMethod?: Record<string, RemoteMethodType>;
  isInsert?: boolean; // 连接器新增的时候日期组件不管操作符是什么只需要传一个值
  isConnector?: boolean; // 判断是不是连接器
};

// 组件绑定值
const bindMap: Record<string, CompBindType> = {
  customer: {
    placeholder: t('common.placeholder.selectCustomer'),
    multiple: true,
    collapsed: true,
    remoteMethod: searchCustomer,
  },
  related_customer: {
    placeholder: t('common.placeholder.selectCustomer'),
    multiple: true,
    collapsed: true,
    remoteMethod: searchCustomer,
  },
  related_customers: {
    placeholder: t('common.placeholder.selectCustomer'),
    multiple: true,
    collapsed: true,
    remoteMethod: searchCustomer,
  },
  parentCustomer: {
    placeholder: t('common.placeholder.selectCustomer'),
    multiple: true,
    collapsed: true,
    remoteMethod: searchCustomer,
  },
  product: {
    placeholder: t('common.placeholder.selectProduct'),
    remoteMethod: searchProduct,
  },
  tlmName: {
    multiple: true,
    collapsed: true,
    // disableMap: true,
    placeholder: t('common.placeholder.selectContact'),
    remoteMethod: searchLinkman,
  },
  linkman: {
    multiple: true,
    collapsed: true,
    // disableMap: true,
    placeholder: t('common.placeholder.selectContact'),
    remoteMethod: searchLinkman,
  },
  user: {
    remoteMethod: searchUserTag,
  },
  // 产品类型
  related_catalog: {
    remoteMethod: searchRelatedCatalog,
  },
  // 故障库 产品类型
  productType: {
    placeholder: t('common.placeholder.selectProductType'),
    remoteMethod: searchProductType,
  },
  // 服务商
  serviceProviders: {
    placeholder: t('common.placeholder.selectServiceProvider'),
    collapsed: true,
    remoteMethod: searchServiceProviders,
  },
  // 关联表单
  relationForm: {
    placeholder: t('common.placeholder.inputKeyWordToSearch'),
  },
  // start 连接器项目
  serialNumber: {
    placeholder: t('common.placeholder.input'),
  },
  // 知识库角色
  role: {
    multiple: true,
    collapsed: true,
    placeholder: t('common.placeholder.selectRole'),
    remoteMethod: searchRole,
  },
  // end 连接器项目
  // 服务项目名称
  svcProjectName: {
    placeholder: t('common.product.selectServiceItemName'),
    remoteMethod: searchServiceItemName,
  },
  // 任务管理-所属项目
  projectId: {
    remoteMethod: searchProjectId,
  },
  // 服务商-授权产品目录
  authorizeProduct: {
    remoteMethod: searchGetProductTypeList,
  },
  // 服务商-标签
  tagLabel: {
    remoteMethod: searchProvideAllLabel,
  },
};

// 组件绑定值
export function genComponent(opts: ComponentOption) {
  const { field, operator, remoteMethod, isInsert, isConnector } = opts;
  const { fieldName, formType } = opts.field;

  const defaultComponentName = formType ? `${formType}-search` : '';
  // 计算渲染组件名称
  let component = specialFieldCompMap[fieldName] ?? specialFieldCompMap[formType] ?? defaultComponentName;

  // 里程处理
  if (['taskEstimatedMileage', 'estimatedMileage', 'actualMileage'].includes(fieldName)) {
    if (['gt', 'ge', 'lt', 'le'].includes(operator)) {
      // 等于、不等于、大于、大于等于、小于、小于等于 使用 input数字输入框
      component = 'number-search';
    } else if (operator === 'between') {
      // 介于 使用数字区间输入框
      component = 'number-section';
    }
  }
  // 空条件组件
  if(['isNull'].includes(operator)){
    component = ''
  }

  // 项目管理 客户地址
  if (field.tableName == TableNameEnum.Project && fieldName == ProjectManageFieldNameMappingEnum.Address) {
    component = 'text-search'
  }

  if (isConnector ) {
    switch (formType) {
      case 'related_task':
        // 如果是连接器的关联工单字段由于传值方式不一致使用connector-related-task-search跟之前的高级搜索里面的关联工单区分
        component = 'connector-related-task-search'
        break;                      
      
      default:
        break;
    }
  }
  
  // 设置组件绑定值
  const bind: CompBindType = {
    placeholder: genPlaceholder(field),
    ...(bindMap[fieldName] ?? bindMap[formType] ?? {}),
  };
  bind.multiple = isMultiValue(operator);
  bind.collapsed = bind.multiple; // 多选的折叠显示

  // setting 处理
  field.setting = isString(field.setting) ? parse(field.setting) : field.setting || {};

  if (field.formType === 'select' && !field.setting.isMulti && !field.isSystem) {
    field.setting.isMulti = true; // 自定义下拉菜单都是多选
    bind.multiple = true;
  } else if (field.formType === 'cascader') {
    // 多级菜单
    bind.multiple = !!field.setting.isMulti;
  } else {
    // 其他类型的下拉菜单
    field.setting.isMulti = bind.multiple;
  }

  if (field.formType === 'select' && isConnector) {
    // 连接器的下拉菜单都是单选
    field.setting.isMulti = false;
    bind.multiple = false;
  }

  field.setting.selectType = 1; // 改为下拉模式

  // date 处理

  // 需求时间只需要区间
  if (component === 'date-search') {
    bind.isRange = operator?.toLocaleLowerCase() === 'between'
    bind.type = field.formType === 'datetime' ? 'datetime' :'date'; // 这里只需要放 date 或者 dateTime
    if (['planStartTime', 'planEndTime', 'planTime'].includes(field.fieldName)) {
      bind.type = 'datetime';
    }
    if(['gt', 'lt', 'le', 'ge'].includes(operator)){
      bind.type = 'datetime';
    }
    if (isInsert) {
      // 连接器新增日期类型字段type固定为date
      bind.isRange = false;
      bind.type = 'date';
    }
  }

  if ((isConnector && formType === 'number' && operator?.toLocaleLowerCase() === 'between') || operator?.toLocaleLowerCase() === 'not_between') {
    // 如果是连接器的关联工单字段由于传值方式不一致使用connector-related-task-search跟之前的高级搜索里面的关联工单区分
    component = 'number-range';
  }

  // remote method
  const _remoteMethod = remoteMethod ? remoteMethod[fieldName] ?? remoteMethod[formType] : undefined;

  bind.remoteMethod = _remoteMethod ?? bind.remoteMethod;

  return {
    component,
    bind,
  };
}
